package org.lanyu.springainovel.novel.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.lanyu.springainovel.novel.entity.ChapterContent;
import org.lanyu.springainovel.novel.entity.BookOutline;
import org.lanyu.springainovel.novel.entity.Book;
import org.lanyu.springainovel.novel.mapper.ChapterContentMapper;
import org.lanyu.springainovel.novel.service.ChapterContentService;
import org.lanyu.springainovel.novel.service.NovelOutlineService;
import org.lanyu.springainovel.novel.service.BookService;
import org.lanyu.springainovel.novel.service.BookRoleService;
import org.lanyu.springainovel.novel.dto.ChapterOutlineGenerationRequest;
import org.lanyu.springainovel.novel.dto.ChapterOutlineGenerationResponse;
import org.lanyu.springainovel.novel.dto.ChapterContentGenerationRequest;
import org.lanyu.springainovel.novel.dto.ChapterOutline;
import org.lanyu.springainovel.common.config.ChatModelManager;
import org.lanyu.springainovel.chat.service.PromptTemplateService;
import org.lanyu.springainovel.common.entity.MyPromptTemplate;
import org.lanyu.springainovel.common.service.AsyncTaskWebSocketService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.converter.BeanOutputConverter;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.time.LocalDateTime;
import java.util.List;
import java.util.ArrayList;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 章节正文服务实现类
 */
@Slf4j
@Service
public class ChapterContentServiceImpl extends ServiceImpl<ChapterContentMapper, ChapterContent> implements ChapterContentService, ApplicationContextAware {

    private ApplicationContext applicationContext;
    
    @Autowired
    private BookRoleService bookRoleService;

    private final NovelOutlineService novelOutlineService;
    private final BookService bookService;
    private final ChatModelManager chatModelManager;
    private final PromptTemplateService promptTemplateService;
    private final AsyncTaskWebSocketService asyncTaskWebSocketService;

    public ChapterContentServiceImpl(NovelOutlineService novelOutlineService, BookService bookService, 
                                   ChatModelManager chatModelManager, PromptTemplateService promptTemplateService,
                                   AsyncTaskWebSocketService asyncTaskWebSocketService) {
        this.novelOutlineService = novelOutlineService;
        this.bookService = bookService;
        this.chatModelManager = chatModelManager;
        this.promptTemplateService = promptTemplateService;
        this.asyncTaskWebSocketService = asyncTaskWebSocketService;
    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public List<ChapterContent> getChaptersByBookId(Long bookId) {
        QueryWrapper<ChapterContent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.orderByAsc("chapter_number");
        return this.list(queryWrapper);
    }

    @Override
    public ChapterContent getChapterByBookIdAndNumber(Long bookId, Integer chapterNumber) {
        QueryWrapper<ChapterContent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.eq("chapter_number", chapterNumber);
        return this.getOne(queryWrapper);
    }

    @Override
    public ChapterContent saveOrUpdateChapter(ChapterContent chapter) {
        if (chapter.getId() == null) {
            chapter.setCreateTime(LocalDateTime.now());
        }
        chapter.setUpdateTime(LocalDateTime.now());
        
        // 默认状态为草稿
        if (chapter.getStatus() == null) {
            chapter.setStatus(0);
        }
        
        // 默认版本号为1
        if (chapter.getVersion() == null) {
            chapter.setVersion(1);
        }
        
        // 处理字数字段：如果正文为空或null，则字数设为0
        if (chapter.getContent() == null || chapter.getContent().trim().isEmpty()) {
            chapter.setWordNum(0);
        } else {
            // 计算正文字数（去除空白字符后的字符数）
            String content = chapter.getContent().trim();
            // 简单的字数统计，去除所有空白字符后的字符数
            int wordCount = content.replaceAll("\\s+", "").length();
            chapter.setWordNum(wordCount);
        }
        
        this.saveOrUpdate(chapter);
        return chapter;
    }

    @Override
    public ChapterContent getChapterById(Long id) {
        return this.getById(id);
    }
    
    @Override
    public Page<ChapterContent> getChapterOutlinesByBookId(Long bookId, Integer pageNum, Integer pageSize) {
        // 创建分页对象
        Page<ChapterContent> page = new Page<>(pageNum, pageSize);
        
        // 创建查询条件
        QueryWrapper<ChapterContent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.orderByAsc("chapter_number");
        
        // 只查询需要的字段：章节数、章节标题、细纲内容
        queryWrapper.select("id", "book_id", "chapter_number", "chapter_title", "chapter_outline");
        
        // 执行分页查询
        Page<ChapterContent> chapterPage = this.page(page, queryWrapper);
        
        return chapterPage;
    }
    
    @Override
    public ChapterOutlineGenerationResponse generateChapterOutlines(ChapterOutlineGenerationRequest request, Long userId) {
        String bookIdStr = request.getBookId().toString();
        
        try {
            // 发送开始生成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 5, "开始生成章节细纲", null);
            
            // 1. 验证用户权限和书籍信息
            Book book = bookService.getById(request.getBookId());
            if (book == null) {
                throw new RuntimeException("书籍不存在，ID: " + request.getBookId());
            }
            
            if (!book.getUserId().equals(userId)) {
                throw new RuntimeException("无权访问该书籍，ID: " + request.getBookId());
            }
            
            // 发送验证完成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 10, "验证用户权限和书籍信息完成", null);
            
            // 2. 查询书籍大纲信息
            BookOutline outline = novelOutlineService.getOutlineByBookId(request.getBookId());
            if (outline == null) {
                throw new RuntimeException("该书籍暂无大纲信息，请先生成大纲");
            }
            
            // 发送查询大纲完成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 15, "查询书籍大纲信息完成", null);
            
            // 3. 确定开始章节号
            Integer startChapterNumber = determineStartChapterNumber(request.getBookId(), request.getStartChapterNumber());
            
            // 发送确定章节号完成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 20, "确定开始章节号完成", null);
            
            // 4. 获取AI模型
            ChatModel chatModel = chatModelManager.getOrCreateChatModelById(request.getModelId());
            
            // 发送获取模型完成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 25, "获取AI模型完成: " + chatModel.getDefaultOptions().getModel(), null);
            
            // 5. 获取系统提示词
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 30, "正在获取系统提示词", null);
            String systemPrompt = getSystemPromptWithFormat(request.getPromptTemplateId());
            
            // 发送获取系统提示词完成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 35, "获取系统提示词完成", null);
            
            // 6. 构建用户提示词
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 40, "正在构建用户提示词", null);
            String userPrompt = buildUserPrompt(outline, startChapterNumber, request.getChapterCount());
            
            // 发送构建用户提示词完成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 45, "构建用户提示词完成", null);
            
            // 7. 调用AI模型生成章节细纲
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 50, "正在等待模型响应", null);
            List<ChapterOutline> chapterOutlines = generateChapterOutlinesWithAI(
                chatModel, systemPrompt, userPrompt, request.getChapterCount());
            
            // 发送AI模型响应完成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 70, "AI模型响应完成，正在处理响应数据", null);
            
            // 8. 批量保存章节细纲到数据库
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 75, "正在保存章节细纲到数据库", null);
            saveChapterOutlinesToDatabase(request.getBookId(), chapterOutlines, startChapterNumber);
            
            // 发送保存完成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 90, "保存章节细纲到数据库完成", null);
            
            // 9. 构建响应
            ChapterOutlineGenerationResponse response = new ChapterOutlineGenerationResponse();
            response.setChapterOutlines(chapterOutlines);
            response.setActualChapterCount(chapterOutlines.size());
            response.setStartChapterNumber(startChapterNumber);
            response.setEndChapterNumber(startChapterNumber + chapterOutlines.size() - 1);
            
            log.info("成功生成章节细纲，书籍ID: {}, 开始章节: {}, 生成数量: {}", 
                request.getBookId(), startChapterNumber, chapterOutlines.size());
            
            // 发送完成的消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "RUNNING", 95, "正在构建响应数据", null);
            
            return response;
        } catch (Exception e) {
            log.error("生成章节细纲失败", e);
            
            // 发送失败消息
            asyncTaskWebSocketService.sendChapterOutlineGenerationMessage(bookIdStr, "FAILED", null, "生成章节细纲失败: " + e.getMessage(), null);
            
            throw new RuntimeException("生成章节细纲失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 确定开始章节号
     * 
     * @param bookId 书籍ID
     * @param requestStartChapterNumber 请求中指定的开始章节号（可为null）
     * @return 实际开始章节号
     */
    private Integer determineStartChapterNumber(Long bookId, Integer requestStartChapterNumber) {
        // 如果请求中指定了开始章节号，直接使用
        if (requestStartChapterNumber != null) {
            log.info("使用请求中指定的开始章节号: {}", requestStartChapterNumber);
            return requestStartChapterNumber;
        }
        
        // 否则查询该书籍已有的最新章节编号
        QueryWrapper<ChapterContent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.orderByDesc("chapter_number");
        queryWrapper.last("LIMIT 1");
        
        ChapterContent latestChapter = this.getOne(queryWrapper);
        
        // 如果没有已有章节，从第1章开始
        if (latestChapter == null) {
            log.info("书籍{}暂无章节，从第1章开始生成", bookId);
            return 1;
        }
        
        // 否则从最新章节的下一章开始
        Integer nextChapterNumber = latestChapter.getChapterNumber() + 1;
        log.info("书籍{}最新章节为第{}章，从第{}章开始生成", bookId, latestChapter.getChapterNumber(), nextChapterNumber);
        return nextChapterNumber;
    }
    
    /**
     * 获取系统提示词（包含格式化指令）
     * 
     * @param promptTemplateId 提示词模板ID
     * @return 系统提示词
     */
    private String getSystemPromptWithFormat(Long promptTemplateId) {
        String basePrompt;
        
        if (promptTemplateId == null) {
            // 使用默认提示词
            basePrompt = "你是一个专业的小说编辑，擅长根据小说大纲生成详细的章节细纲。请根据提供的信息，为每个章节生成一个标题和详细的章节概要。";
        } else {
            // 从服务获取提示词模板
            MyPromptTemplate promptTemplate = promptTemplateService.getTemplateById(promptTemplateId);
            if (promptTemplate == null || promptTemplate.getContent() == null || promptTemplate.getContent().isEmpty()) {
                // 使用默认提示词
                basePrompt = "你是一个专业的小说编辑，擅长根据小说大纲生成详细的章节细纲。请根据提供的信息，为每个章节生成一个标题和详细的章节概要。";
            } else {
                basePrompt = promptTemplate.getContent();
                
                // 增加模板使用次数
                promptTemplateService.incrementUsageCount(promptTemplateId);
            }
        }
        
        // 添加JSON格式要求
        String jsonFormatInstructions = "\n\n重要提示：\n" +
            "1. 请严格按照以下JSON格式返回结果，不要添加任何额外的说明文字\n" +
            "2. 确保JSON格式正确，所有字符串都用双引号包围\n" +
            "3. 直接返回JSON数组，不要使用代码块标记(如```json)";
        
        // 添加格式化指令到系统提示词
        BeanOutputConverter<List<ChapterOutline>> outputConverter = new BeanOutputConverter<>(new org.springframework.core.ParameterizedTypeReference<List<ChapterOutline>>() {});
        String formatInstruction = "\n\n请严格按照以下JSON格式返回结果：\n" + outputConverter.getFormat();
        
        return basePrompt + jsonFormatInstructions + formatInstruction;
    }
    
    /**
     * 构建用户提示词
     * 
     * @param outline 书籍大纲
     * @param startChapterNumber 开始章节号
     * @param chapterCount 生成章节数量
     * @return 用户提示词
     */
    private String buildUserPrompt(BookOutline outline, Integer startChapterNumber, Integer chapterCount) {
        StringBuilder promptBuilder = new StringBuilder();
        
        promptBuilder.append("请根据以下小说大纲信息，从第").append(startChapterNumber)
            .append("章开始，生成").append(chapterCount).append("个章节的细纲：\n\n");
        
        // 添加主线剧情
        if (outline.getOutlineDetails() != null && !outline.getOutlineDetails().isEmpty()) {
            promptBuilder.append("【小说大纲】\n").append(outline.getOutlineDetails()).append("\n\n");
        }

        // 添加大纲规划
        if (outline.getChapterPlanning() != null && !outline.getChapterPlanning().isEmpty()) {
            promptBuilder.append("【章节规划】\n");
            promptBuilder.append(outline.getChapterPlanning());
        }
        
        // 如果要生成的章节细纲开始章节>1，则添加已有的章节细纲，确保生成的细纲情节连贯
        if (startChapterNumber > 1) {
            
            // 查询已有的章节细纲，最多查询前50章
            QueryWrapper<ChapterContent> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("book_id", outline.getBookId());
            queryWrapper.lt("chapter_number", startChapterNumber);
            queryWrapper.orderByAsc("chapter_number");
            queryWrapper.last("LIMIT 50");
            
            List<ChapterContent> existingChapters = this.list(queryWrapper);
            
            if (existingChapters != null && !existingChapters.isEmpty()) {
                promptBuilder.append("【已有章节细纲】\n");
                promptBuilder.append("以下是该书籍已有的章节细纲，请确保新章节与已有章节保持连贯性：\n\n");
                for (ChapterContent chapter : existingChapters) {
                    promptBuilder.append("第").append(chapter.getChapterNumber()).append("章：")
                        .append(chapter.getChapterTitle()).append("\n");
                    
                    // 添加章节细纲内容
                    if (chapter.getChapterOutline() != null && !chapter.getChapterOutline().isEmpty()) {
                        promptBuilder.append(chapter.getChapterOutline()).append("\n");
                    }
                    
                    promptBuilder.append("\n");
                }
            }
            
            promptBuilder.append("\n");
        }
        
        return promptBuilder.toString();
    }
    
    /**
     * 使用AI模型生成章节细纲
     * 
     * @param chatModel 聊天模型
     * @param systemPrompt 系统提示词
     * @param userPrompt 用户提示词
     * @param chapterCount 期望的章节数量
     * @return 章节细纲列表
     */
    private List<ChapterOutline> generateChapterOutlinesWithAI(
            ChatModel chatModel, String systemPrompt, String userPrompt, Integer chapterCount) {
        try {
            // 创建ChatClient
            ChatClient chatClient = ChatClient.builder(chatModel).build();
            
            // 创建输出转换器
            BeanOutputConverter<List<ChapterOutline>> outputConverter = 
                new BeanOutputConverter<>(new org.springframework.core.ParameterizedTypeReference<List<ChapterOutline>>() {});
            
            // 构建提示词
            Prompt prompt = new Prompt(List.of(
                new SystemMessage(systemPrompt),
                new UserMessage(userPrompt)
            ));
            
            // 调用模型
            String response = chatClient.prompt(prompt).call().content();
            
            // 记录原始响应用于调试
            log.info("AI原始响应: {}", response);
            
            // 预处理响应，确保JSON格式正确
            String processedResponse = preprocessJsonResponse(response);
            
            // 记录处理后的响应用于调试
            log.info("处理后的JSON: {}", processedResponse);
            
            // 尝试解析响应
            List<ChapterOutline> chapterOutlines;
            try {
                chapterOutlines = outputConverter.convert(processedResponse);
            } catch (Exception e) {
                log.error("JSON解析失败，尝试进一步处理: {}", e.getMessage());
                
                // 如果第一次解析失败，尝试更激进的修复方法
                String repairedJson = attemptJsonRepair(processedResponse);
                log.info("修复后的JSON: {}", repairedJson);
                
                try {
                    chapterOutlines = outputConverter.convert(repairedJson);
                } catch (Exception e2) {
                    log.error("修复后的JSON仍然无法解析: {}", e2.getMessage());
                    
                    // 最后尝试：手动解析JSON
                    chapterOutlines = manualJsonParse(processedResponse);
                }
            }
            
            // 验证章节数量
            if (chapterOutlines.size() != chapterCount) {
                log.warn("生成的章节数量({})与期望数量({})不匹配", chapterOutlines.size(), chapterCount);
            }
            
            return chapterOutlines;
        } catch (Exception e) {
            log.error("使用AI模型生成章节细纲失败", e);
            throw new RuntimeException("使用AI模型生成章节细纲失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 手动解析JSON，作为最后的备选方案
     * 
     * @param jsonString JSON字符串
     * @return 章节细纲列表
     */
    private List<ChapterOutline> manualJsonParse(String jsonString) {
        List<ChapterOutline> result = new ArrayList<>();
        
        try {
            // 简单的手动解析，只处理基本格式
            // 移除数组开始和结束的括号
            String content = jsonString.trim();
            if (content.startsWith("[") && content.endsWith("]")) {
                content = content.substring(1, content.length() - 1);
            }
            
            // 分割对象
            String[] objects = content.split("\\},\\s*\\{");
            
            for (int i = 0; i < objects.length; i++) {
                String objStr = objects[i];
                
                // 确保对象有正确的开始和结束
                if (!objStr.startsWith("{")) {
                    objStr = "{" + objStr;
                }
                if (!objStr.endsWith("}")) {
                    objStr = objStr + "}";
                }
                
                // 提取字段值
                ChapterOutline outline = new ChapterOutline();
                
                // 提取chapterNumber
                int chapterNumberStart = objStr.indexOf("\"chapterNumber\":");
                if (chapterNumberStart >= 0) {
                    int valueStart = objStr.indexOf(":", chapterNumberStart) + 1;
                    int valueEnd = findValueEnd(objStr, valueStart);
                    String valueStr = objStr.substring(valueStart, valueEnd).trim();
                    
                    try {
                        outline.setChapterNumber(Integer.parseInt(valueStr));
                    } catch (NumberFormatException e) {
                        log.warn("无法解析chapterNumber: {}", valueStr);
                        outline.setChapterNumber(i + 1);
                    }
                } else {
                    outline.setChapterNumber(i + 1);
                }
                
                // 提取title
                int titleStart = objStr.indexOf("\"title\":");
                if (titleStart >= 0) {
                    int valueStart = objStr.indexOf("\"", titleStart + 8) + 1;
                    int valueEnd = objStr.indexOf("\"", valueStart);
                    if (valueEnd > valueStart) {
                        outline.setTitle(objStr.substring(valueStart, valueEnd));
                    }
                }
                
                // 提取summary
                int summaryStart = objStr.indexOf("\"summary\":");
                if (summaryStart >= 0) {
                    int valueStart = objStr.indexOf("\"", summaryStart + 10) + 1;
                    int valueEnd = objStr.indexOf("\"", valueStart);
                    if (valueEnd > valueStart) {
                        outline.setSummary(objStr.substring(valueStart, valueEnd));
                    }
                }
                
                result.add(outline);
            }
            
            log.info("手动解析成功，提取了{}个章节细纲", result.size());
            return result;
            
        } catch (Exception e) {
            log.error("手动解析JSON失败", e);
            throw new RuntimeException("无法解析AI返回的JSON数据: " + e.getMessage(), e);
        }
    }
    
    /**
     * 查找值的结束位置
     * 
     * @param str 字符串
     * @param start 开始位置
     * @return 结束位置
     */
    private int findValueEnd(String str, int start) {
        if (start >= str.length()) {
            return str.length();
        }
        
        char c = str.charAt(start);
        
        // 如果是字符串值（以引号开始）
        if (c == '"') {
            int end = str.indexOf('"', start + 1);
            // 处理转义引号
            while (end > 0 && str.charAt(end - 1) == '\\') {
                end = str.indexOf('"', end + 1);
            }
            return end > 0 ? end + 1 : str.length();
        }
        
        // 如果是数字或布尔值
        int end = start;
        while (end < str.length() && 
               (str.charAt(end) != ',' && str.charAt(end) != '}' && !Character.isWhitespace(str.charAt(end)))) {
            end++;
        }
        
        return end;
    }
    
    /**
     * 预处理AI响应，确保JSON格式正确
     * 
     * @param response AI原始响应
     * @return 处理后的JSON字符串
     */
    private String preprocessJsonResponse(String response) {
        if (response == null || response.trim().isEmpty()) {
            return response;
        }
        
        // 记录原始响应用于调试
        log.debug("AI原始响应: {}", response);
        
        // 尝试提取JSON部分
        String jsonContent = response.trim();
        
        // 处理反引号问题 - 移除所有反引号
        jsonContent = jsonContent.replace("`", "");
        
        // 如果响应包含json标记，提取其中的JSON内容
        if (jsonContent.startsWith("json")) {
            // 找到下一个json出现的位置，这通常是结束标记
            int endIndex = jsonContent.indexOf("json", 4);
            if (endIndex > 0) {
                jsonContent = jsonContent.substring(4, endIndex).trim();
            } else {
                // 如果没有找到结束标记，则取从第4个字符开始的所有内容
                jsonContent = jsonContent.substring(4).trim();
            }
        }
        
        // 尝试找到JSON数组的开始和结束
        int startIndex = jsonContent.indexOf('[');
        int endIndex = jsonContent.lastIndexOf(']');
        
        if (startIndex >= 0 && endIndex > startIndex) {
            jsonContent = jsonContent.substring(startIndex, endIndex + 1);
        }
        
        log.debug("处理后的JSON: {}", jsonContent);
        return jsonContent;
    }
    
    /**
     * 批量保存章节细纲到数据库
     * 
     * @param bookId 书籍ID
     * @param chapterOutlines 章节细纲列表
     * @param startChapterNumber 开始章节号
     */
    private void saveChapterOutlinesToDatabase(Long bookId, List<ChapterOutline> chapterOutlines, Integer startChapterNumber) {
        if (chapterOutlines == null || chapterOutlines.isEmpty()) {
            log.warn("章节细纲列表为空，无需保存");
            return;
        }
        
        try {
            // 计算章节范围
            Integer endChapterNumber = startChapterNumber + chapterOutlines.size() - 1;
            
            // 先删除指定章节范围内的数据
            QueryWrapper<ChapterContent> deleteQueryWrapper = new QueryWrapper<>();
            deleteQueryWrapper.eq("book_id", bookId);
            deleteQueryWrapper.between("chapter_number", startChapterNumber, endChapterNumber);
            
            int deletedCount = this.getBaseMapper().delete(deleteQueryWrapper);
            if (deletedCount > 0) {
                log.info("已删除{}个旧章节细纲，书籍ID: {}, 章节范围: {}-{}", 
                    deletedCount, bookId, startChapterNumber, endChapterNumber);
            }
            
            // 准备新章节数据
            List<ChapterContent> chapters = new ArrayList<>();
            
            for (int i = 0; i < chapterOutlines.size(); i++) {
                ChapterOutline outline = chapterOutlines.get(i);
                ChapterContent chapter = new ChapterContent();
                
                chapter.setBookId(bookId);
                chapter.setChapterNumber(startChapterNumber + i);
                chapter.setChapterTitle(outline.getTitle());
                chapter.setChapterOutline(outline.getSummary());
                chapter.setVersion(0); // 当前版本固定为0
                chapter.setStatus(0); // 草稿状态
                chapter.setWordNum(0); // 新创建章节字数默认为0，因为还没有正文内容
                
                chapters.add(chapter);
            }
            
            // 批量插入新章节数据
            boolean result = this.saveBatch(chapters);
            
            if (result) {
                log.info("成功保存{}个章节细纲到数据库，书籍ID: {}, 开始章节号: {}", 
                    chapters.size(), bookId, startChapterNumber);
            } else {
                log.error("保存章节细纲到数据库失败，书籍ID: {}, 开始章节号: {}", bookId, startChapterNumber);
                throw new RuntimeException("保存章节细纲到数据库失败");
            }
        } catch (Exception e) {
            log.error("批量保存章节细纲到数据库失败", e);
            throw new RuntimeException("批量保存章节细纲到数据库失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public Flux<String> generateChapterContentStream(ChapterContentGenerationRequest request, Long userId) {
        try {
            // 1. 验证用户权限和书籍信息
            Book book = bookService.getById(request.getBookId());
            if (book == null) {
                return Flux.just("书籍不存在，ID: " + request.getBookId());
            }
            
            if (!book.getUserId().equals(userId)) {
                return Flux.just("无权访问该书籍，ID: " + request.getBookId());
            }
            
            // 2. 查询书籍大纲信息
            BookOutline outline = novelOutlineService.getOutlineByBookId(request.getBookId());
            if (outline == null) {
                return Flux.just("该书籍暂无大纲信息，请先生成大纲");
            }
            
            // 3. 查询当前章节信息
            ChapterContent currentChapter = getChapterByBookIdAndNumber(request.getBookId(), request.getChapterNumber());
            if (currentChapter == null) {
                return Flux.just("章节不存在，书籍ID: " + request.getBookId() + ", 章节号: " + request.getChapterNumber());
            }
            
            // 4. 获取AI模型
            ChatModel chatModel = chatModelManager.getOrCreateChatModelById(request.getModelId());
            
            // 5. 获取系统提示词
            String systemPrompt = getSystemPrompt(request.getSystemPromptTemplateId());
            
            // 6. 构建用户提示词
            String userPrompt = buildContentUserPrompt(outline, currentChapter, request.getChapterNumber());
            
            // 7. 创建ChatClient
            ChatClient chatClient = ChatClient.builder(chatModel).build();
            
            // 8. 生成流式响应
            return chatClient.prompt()
                    .system(systemPrompt)
                    .user(userPrompt)
                    .stream()
                    .content()
                    .doOnError(error -> log.error("生成章节正文流式响应失败", error))
                    .onErrorResume(error -> Flux.just("生成章节正文失败: " + (error.getMessage() != null ? error.getMessage() : "未知错误")));
        } catch (Exception e) {
            log.error("生成章节正文失败", e);
            return Flux.just("生成章节正文失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取系统提示词
     * 
     * @param promptTemplateId 提示词模板ID
     * @return 系统提示词
     */
    private String getSystemPrompt(Long promptTemplateId) {
        // 从服务获取提示词模板
        MyPromptTemplate promptTemplate = promptTemplateService.getTemplateById(promptTemplateId);
        if (promptTemplate == null || promptTemplate.getContent() == null || promptTemplate.getContent().isEmpty()) {
            throw new RuntimeException("提示词模板不存在或内容为空，ID: " + promptTemplateId);
        }
        
        // 增加模板使用次数
        promptTemplateService.incrementUsageCount(promptTemplateId);
        
        return promptTemplate.getContent();
    }
    
    /**
     * 构建生成章节正文的用户提示词
     *
     * @param outline 书籍大纲
     * @param currentChapter 当前章节
     * @param chapterNumber 章节号
     * @return 用户提示词
     */
    private String buildContentUserPrompt(BookOutline outline, ChapterContent currentChapter, Integer chapterNumber) {
        StringBuilder promptBuilder = new StringBuilder();

        promptBuilder.append("请根据以下信息，为第").append(chapterNumber)
            .append("章生成正文内容：\n\n");

        // 添加章节标题
        promptBuilder.append("【章节标题】\n").append(currentChapter.getChapterTitle()).append("\n\n");

        // 添加主线剧情
        if (outline.getOutlineDetails() != null && !outline.getOutlineDetails().isEmpty()) {
            promptBuilder.append("【小说大纲】\n").append(outline.getOutlineDetails()).append("\n\n");
        }

        // 添加章节细纲
        if (currentChapter.getChapterOutline() != null && !currentChapter.getChapterOutline().isEmpty()) {
            promptBuilder.append("【本章节细纲】\n").append(currentChapter.getChapterOutline()).append("\n\n");
        }

        // 添加角色信息 - 使用isActive字段为1的角色
        try {
            org.lanyu.springainovel.novel.entity.BookRole activeCharacterProfile = 
                bookRoleService.getActiveCharacterProfile(outline.getBookId());
            
            if (activeCharacterProfile != null && activeCharacterProfile.getCharacterProfile() != null 
                && !activeCharacterProfile.getCharacterProfile().isEmpty()) {
                promptBuilder.append("【角色信息】\n").append(activeCharacterProfile.getCharacterProfile()).append("\n\n");
            }
        } catch (Exception e) {
            log.warn("获取角色信息失败，将不包含角色信息：{}", e.getMessage());
        }

        // 如果要生成的章节不是第一章，则添加前两章的正文作为上下文
        if (chapterNumber > 1) {

            // 查询前两章的正文
            QueryWrapper<ChapterContent> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("book_id", outline.getBookId());
            queryWrapper.lt("chapter_number", chapterNumber);
            queryWrapper.orderByDesc("chapter_number");
            queryWrapper.last("LIMIT 2");

            List<ChapterContent> previousChapters = this.list(queryWrapper);

            if (previousChapters != null && !previousChapters.isEmpty()) {
                promptBuilder.append("【前文内容】\n");
                promptBuilder.append("以下是该书籍前两章的正文内容，请确保新章节与前文情节连贯：\n\n");
                // 按章节号升序排列
                previousChapters.sort((a, b) -> a.getChapterNumber().compareTo(b.getChapterNumber()));

                for (ChapterContent chapter : previousChapters) {
                    promptBuilder.append("第").append(chapter.getChapterNumber()).append("章：")
                        .append(chapter.getChapterTitle()).append("\n");

                    // 添加章节正文内容
                    if (chapter.getContent() != null && !chapter.getContent().isEmpty()) {
                        promptBuilder.append(chapter.getContent()).append("\n");
                    }

                    promptBuilder.append("\n");
                }
            }

            promptBuilder.append("\n");
        }

        return promptBuilder.toString();
    }

    /**
     * 生成章节正文
     * 
     * @param request 生成章节正文请求
     * @param userId 用户ID
     * @return 章节内容
     */
    @Override
    public ChapterContent generateChapterContent(ChapterContentGenerationRequest request, Long userId) {
        try {
            // 1. 验证用户权限和书籍信息
            Book book = bookService.getById(request.getBookId());
            if (book == null) {
                throw new RuntimeException("书籍不存在，ID: " + request.getBookId());
            }
            
            if (!book.getUserId().equals(userId)) {
                throw new RuntimeException("无权访问该书籍，ID: " + request.getBookId());
            }
            
            // 2. 查询书籍大纲信息
            BookOutline outline = novelOutlineService.getOutlineByBookId(request.getBookId());
            if (outline == null) {
                throw new RuntimeException("该书籍暂无大纲信息，请先生成大纲");
            }
            
            // 3. 查询当前章节信息
            ChapterContent currentChapter = getChapterByBookIdAndNumber(request.getBookId(), request.getChapterNumber());
            if (currentChapter == null) {
                throw new RuntimeException("章节不存在，书籍ID: " + request.getBookId() + ", 章节号: " + request.getChapterNumber());
            }
            
            // 4. 获取AI模型
            ChatModel chatModel = chatModelManager.getOrCreateChatModelById(request.getModelId());
            
            // 5. 获取系统提示词
            String systemPrompt = getSystemPrompt(request.getSystemPromptTemplateId());
            
            // 6. 构建用户提示词
            String userPrompt = buildContentUserPrompt(outline, currentChapter, request.getChapterNumber());
            
            // 7. 创建ChatClient
            ChatClient chatClient = ChatClient.builder(chatModel).build();
            
            // 8. 调用AI模型生成章节正文
            String content = chatClient.prompt()
                    .system(systemPrompt)
                    .user(userPrompt)
                    .call()
                    .content();
            
            // 9. 更新章节内容
            currentChapter.setContent(content);
            currentChapter.setUpdateTime(LocalDateTime.now());
            
            // 10. 计算并更新字数
            if (content == null || content.trim().isEmpty()) {
                currentChapter.setWordNum(0);
            } else {
                // 计算正文字数（去除空白字符后的字符数）
                String trimmedContent = content.trim();
                int wordCount = trimmedContent.replaceAll("\\s+", "").length();
                currentChapter.setWordNum(wordCount);
            }
            
            // 11. 保存到数据库
            this.updateById(currentChapter);
            
            log.info("成功生成章节正文，书籍ID: {}, 章节号: {}", request.getBookId(), request.getChapterNumber());
            
            return currentChapter;
        } catch (Exception e) {
            log.error("生成章节正文失败", e);
            throw new RuntimeException("生成章节正文失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 尝试修复JSON格式问题
     * 
     * @param jsonString 原始JSON字符串
     * @return 修复后的JSON字符串
     */
    private String attemptJsonRepair(String jsonString) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return jsonString;
        }
        
        try {
            String repaired = jsonString;
            
            // 1. 修复缺少逗号的问题
            // 在对象属性之间添加缺少的逗号
            repaired = repaired.replaceAll("(\"[^\"]*\"\\s*:\\s*\"[^\"]*\")\\s*(\"[^\"]*\"\\s*:)", "$1,$2");
            repaired = repaired.replaceAll("(\"[^\"]*\"\\s*:\\s*\\d+)\\s*(\"[^\"]*\"\\s*:)", "$1,$2");
            
            // 2. 修复多余的逗号问题
            // 移除对象或数组最后一个属性后的逗号
            repaired = repaired.replaceAll(",\\s*}", "}");
            repaired = repaired.replaceAll(",\\s*\\]", "]");
            
            // 3. 修复缺少引号的属性名
            // 确保所有属性名都用双引号包围
            repaired = fixUnquotedPropertyNames(repaired);
            
            return repaired;
        } catch (Exception e) {
            log.error("修复JSON格式时出错: {}", e.getMessage());
            return jsonString; // 返回原始字符串
        }
    }
    
    /**
     * 修复缺少引号的属性名
     * 
     * @param jsonString JSON字符串
     * @return 修复后的JSON字符串
     */
    private String fixUnquotedPropertyNames(String jsonString) {
        // 这个方法尝试修复缺少引号的属性名
        // 例如：{title: "第一章"} -> {"title": "第一章"}
        
        // 使用正则表达式匹配缺少引号的属性名
        // 这个正则表达式会匹配形如 属性名: 的模式，其中属性名不包含引号
        Pattern pattern = Pattern.compile("(\\{\\s*|,\\s*)([a-zA-Z_][a-zA-Z0-9_]*)\\s*:");
        Matcher matcher = pattern.matcher(jsonString);
        StringBuffer sb = new StringBuffer();
        
        while (matcher.find()) {
            String replacement = matcher.group(1) + "\"" + matcher.group(2) + "\":";
            matcher.appendReplacement(sb, replacement);
        }
        matcher.appendTail(sb);
        
        return sb.toString();
    }
}